package cn.jolyoulu.common.api.version.apiverion;

import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.web.servlet.mvc.condition.RequestCondition;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import java.lang.reflect.Method;

/**
 * @Author: JolyouLu
 * @Date: 2023/1/20 15:53
 * @Description
 * 从类和方法级别创建映射实例
 * 自定义请求映射规则，继承springMvc的 RequestMappingHandlerMapping 类重写
 * DispatcherServlet的初始化过程中自动加载的，默认会自动加载所有实现HandlerMapping接口的bean
 */
public class ApiHandlerMapping extends RequestMappingHandlerMapping {

    private final String apiVersionHandler;

    public ApiHandlerMapping(String reqHeader) {
        this.apiVersionHandler = reqHeader;
    }

    /**
     * Spring启动时，扫描到的每个Controller都会调用该方法，获取一个RequestCondition
     */
    @Override
    protected RequestCondition<?> getCustomTypeCondition(Class<?> handlerType) {
        return buildFrom(AnnotationUtils.findAnnotation(handlerType, ApiVersion.class));
    }

    /**
     * Spring启动时，扫描到的每个Controller的方法都会调用该方法，获取一个RequestCondition
     */
    @Override
    protected RequestCondition<?> getCustomMethodCondition(Method method) {
        return buildFrom(AnnotationUtils.findAnnotation(method, ApiVersion.class));
    }

    /**
     * 生成自定义的ApiCondition
     */
    private ApiCondition buildFrom(ApiVersion platform) {
        // 如果没有 建立 @ApiVersion 注解，则给予默认值1.0.0的注解
        return platform == null ? new ApiCondition(new ApiItem(), apiVersionHandler) :
                new ApiCondition(ApiConverter.convert(platform.value()), apiVersionHandler);
    }
}